<template>
  <div class="validate-input-container pb-3">
    <input
      v-if="tag === 'input'"
      class="form-control w-100"
      aria-describedby="emailHelp"
      v-model="inputRef.value"
      :class="{ 'is-invalid': inputRef.error }"
      @blur="validateInput"
      v-bind="$attrs"
    />
    <textarea
      v-else
      class="form-control w-100"
      aria-describedby="emailHelp"
      v-model="inputRef.value"
      :class="{ 'is-invalid': inputRef.error }"
      @blur="validateInput"
      v-bind="$attrs"
    />
    <div v-if="inputRef.error" class="invalid-feedback">{{ inputRef.message }}</div>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, onMounted, PropType, reactive } from 'vue'
import { emitter } from './ValidateForm.vue'
const emailReg = /^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/
interface RuleProp {
  type: 'required' | 'email' | 'password' | 'custom';
  message: string;
  validator?: () => boolean;
}
export type RuleProps = RuleProp[]
type tagType = 'input' | 'textarea'
export default defineComponent({
  props: {
    rules: {
      type: Array as PropType<RuleProps>
    },
    tag: {
      type: String as PropType<tagType>,
      default: 'input'
    },
    modelValue: String
  },
  inheritAttrs: false,
  setup (props, context) {
    const inputRef = reactive({
      // value: props.modelValue || '',
      value: computed({
        get: () => props.modelValue || '',
        set: (newValue:string) => context.emit('update:modelValue', newValue)
      }),
      error: false,
      message: ''
    })
    onMounted(() => {
      emitter.emit('form-item-created', validateInput)
    })
    // const updateValue = (e:KeyboardEvent) => {
    //   const targetValue = (e.target as HTMLInputElement).value
    //   inputRef.value = targetValue
    //   context.emit('update:modelValue', targetValue)
    // }
    const validateInput = () => {
      let passed = true
      if (props.rules) {
        const allPassed = props.rules.every(rule => {
          switch (rule.type) {
            case 'required':
              if (!inputRef.value.trim()) {
                passed = false
                inputRef.message = rule.message
              }
              break
            case 'email':
              if (!emailReg.test(inputRef.value)) {
                passed = false
                inputRef.message = rule.message
              }
              break
            case 'password':
              if (inputRef.value.length < 6) {
                passed = false
                inputRef.message = rule.message
              }
              break
            case 'custom':
              passed = rule.validator ? rule.validator() : true
              inputRef.message = rule.message
              break
            default:
              break
          }
          return passed
        })
        inputRef.error = !allPassed
        return allPassed
      }
      return true
    }
    return {
      inputRef,
      validateInput
    }
  }
})
</script>
